package impl

import (
	"context"

	"dario.cat/mergo"
	"gitee.com/keepalived_0807/Vblog/apps/blog"
	"gitee.com/keepalived_0807/Vblog/common"
	"gitee.com/keepalived_0807/Vblog/exception"
)

// 文章创建
func (b *BlogServiceImpl) CreatedBlog(ctx context.Context, in *blog.CreatedBlogRequest) (*blog.Blog, error) {
	// 验证请求阐述
	if err := in.Validate(); err != nil {
		return nil, exception.ErrValidateFailed(err.Error())
	}
	// 构造实例对象
	ins := blog.NewBlog()
	ins.CreatedBlogRequest = in

	// 入库返回
	if err := b.db.WithContext(ctx).Create(ins).Error; err != nil {
		return nil, err
	}
	return ins, nil
}

func (b *BlogServiceImpl) QueryBlogs(ctx context.Context, in *blog.QueryBlogsRequest) (*blog.BlogSet, error) {
	set := blog.NewBlogSet()
	// 有默认值，不需要用户传参数

	// 查数据库，构造查询条件
	query := b.db.WithContext(ctx).Table("blogs")

	if in.Keywords != "" {
		query = query.Where("title like ?", "%"+in.Keywords+"%")
	}

	err := query.Count(&set.Total).Error
	if err != nil {
		return nil, err
	}

	err = query.Order("created_at desc").Limit(in.PageSize).Offset(in.Offset()).Find(&set.Items).Error
	if err != nil {
		return nil, err
	}
	return set, nil
}

// 文章详情
func (b *BlogServiceImpl) DescribeBlog(ctx context.Context, in *blog.DescribeBlogRequest) (*blog.Blog, error) {
	ins := blog.NewBlog()
	err := b.db.WithContext(ctx).Where("id = ?", in.BlogId).First(ins).Error
	if err != nil {
		return nil, err
	}
	return ins, nil
}

// 文章更新
func (b *BlogServiceImpl) UpdateBlog(ctx context.Context, in *blog.UpdateBlogRequest) (*blog.Blog, error) {
	// 把有更新的对象查询出来
	ins, err := b.DescribeBlog(ctx, blog.NewDescribeBlogsRequest(in.BlogId))
	if err != nil {
		return nil, err
	}
	switch in.UpdateMode {
	case common.UPDATE_MODE_PUT:
		ins.CreatedBlogRequest = in.CreatedBlogRequest
	case common.UPDATE_MODE_PATCH:
		err := mergo.MergeWithOverwrite(ins.CreatedBlogRequest, in.CreatedBlogRequest)
		if err != nil {
			return nil, err
		}
	}

	// 校验
	if err := ins.CreatedBlogRequest.Validate(); err != nil {
		return nil, exception.ErrValidateFailed(err.Error())
	}

	// 保存数据库
	err = b.db.WithContext(ctx).Table("blogs").Save(ins).Error
	if err != nil {
		return nil, err
	}
	return ins, nil
}

// 文章删除
func (b *BlogServiceImpl) DeleteBlog(ctx context.Context, in *blog.DeleteBlogRequest) (*blog.Blog, error) {
	ins, err := b.DescribeBlog(ctx, blog.NewDescribeBlogsRequest(in.BlogId))
	if err != nil {
		return nil, err
	}

	err = b.db.WithContext(ctx).Where("id = ?", in.BlogId).Delete(&blog.Blog{}).Error
	if err != nil {
		return nil, err
	}
	return ins, err
}

// 状态更新
func (b *BlogServiceImpl) UpdateBlogStatus(ctx context.Context, in *blog.UpdateBlogStatusRequest) (*blog.Blog, error) {
	ins, err := b.DescribeBlog(ctx, blog.NewDescribeBlogsRequest(in.BlogId))
	if err != nil {
		return nil, err
	}
	ins.ChangedBlogStatusRequest = in.ChangedBlogStatusRequest
	ins.SetStatus(ins.Status)
	err = b.db.WithContext(ctx).Table("blogs").Where("id = ?", in.BlogId).Updates(ins.ChangedBlogStatusRequest).Error
	if err != nil {
		return nil, err
	}
	return ins, nil
}
